/*
Copyright [2020] [https://www.xiaonuo.vip]

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

Snowy采用APACHE LICENSE 2.0开源协议，您在使用过程中，需要注意以下几点：

1.请不要删除和修改根目录下的LICENSE文件。
2.请不要删除和修改Snowy源码头部的版权声明。
3.请保留源码和相关描述文件的项目出处，作者声明等。
4.分发源码时候，请注明软件出处 https://gitee.com/xiaonuobase/snowy
5.在修改包名，模块名称，项目代码等时，请注明软件出处 https://gitee.com/xiaonuobase/snowy
6.若您的项目无法满足以上几点，可申请商业授权，获取Snowy商业授权许可，请在官网购买授权，地址为 https://www.xiaonuo.vip
 */
package vip.xiaonuo.facedoor.modular.visitor.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.exceptions.ExceptionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.ListUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.http.client.utils.DateUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import reactor.core.Reactor;
import reactor.event.Event;
import vip.xiaonuo.core.context.constant.ConstantContextHolder;
import vip.xiaonuo.core.context.login.LoginContextHolder;
import vip.xiaonuo.core.exception.ServiceException;
import vip.xiaonuo.core.factory.PageFactory;
import vip.xiaonuo.core.pojo.login.SysLoginUser;
import vip.xiaonuo.core.pojo.page.PageResult;
import vip.xiaonuo.core.util.IpAddressUtil;
import vip.xiaonuo.core.util.PoiUtil;
import vip.xiaonuo.facedoor.modular.device.entity.DeviceCategory;
import vip.xiaonuo.facedoor.modular.devicebase.entity.DeviceBase;
import vip.xiaonuo.facedoor.modular.devicebase.service.DeviceBaseService;
import vip.xiaonuo.facedoor.modular.memberdevice.constant.MemberDeviceConstant;
import vip.xiaonuo.facedoor.modular.memberfeatures.entity.MemberFeatures;
import vip.xiaonuo.facedoor.modular.memberfeatures.enums.MemberFeaturesTypeEnum;
import vip.xiaonuo.facedoor.modular.memberuser.vo.MemberImportResultPojoVO;
import vip.xiaonuo.facedoor.modular.memberuser.vo.UserImportResultVO;
import vip.xiaonuo.facedoor.modular.orgdevice.entity.OrgDevice;
import vip.xiaonuo.facedoor.modular.orgdevice.mapper.OrgDeviceMapper;
import vip.xiaonuo.facedoor.modular.topic.EventTopic;
import vip.xiaonuo.facedoor.modular.visitor.constant.VisitorConstant;
import vip.xiaonuo.facedoor.modular.visitor.entity.Visitor;
import vip.xiaonuo.facedoor.modular.visitor.enums.VisitorExceptionEnum;
import vip.xiaonuo.facedoor.modular.visitor.mapper.VisitorMapper;
import vip.xiaonuo.facedoor.modular.visitor.param.VisitorParam;
import vip.xiaonuo.facedoor.modular.visitor.service.FacedoorVisitorService;
import vip.xiaonuo.facedoor.modular.visitor.service.VisitorService;
import vip.xiaonuo.facedoor.modular.visitor.vo.VisitorImportVO;
import vip.xiaonuo.facedoor.modular.visitor.vo.VisitorPageVO;
import vip.xiaonuo.facedoor.modular.visitordevice.entity.VisitorDevice;
import vip.xiaonuo.facedoor.modular.visitordevice.mapper.VisitorDeviceMapper;
import vip.xiaonuo.sys.modular.file.entity.SysFileInfo;
import vip.xiaonuo.sys.modular.file.enums.FileTypeEnum;
import vip.xiaonuo.sys.modular.file.service.SysFileInfoService;
import vip.xiaonuo.sys.modular.org.entity.SysOrg;
import vip.xiaonuo.sys.modular.org.mapper.SysOrgMapper;

import javax.annotation.Resource;
import java.io.File;
import java.util.Date;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * 访客service接口实现类
 *
 * @author 胡鹏达
 * @date 2022-07-25 09:34:39
 */
@Service
@Slf4j
public class FacedoorVisitorServiceImpl implements FacedoorVisitorService {


    @Resource
    private OrgDeviceMapper orgDeviceMapper;

    @Resource
    private VisitorDeviceMapper visitorDeviceMapper;

    @Resource
    private VisitorMapper visitorMapper;

    @Resource
    private SysFileInfoService sysFileInfoService;

    @Resource
    private SysOrgMapper sysOrgMapper;

    @Resource
    private DeviceBaseService deviceBaseService;

    @Autowired
    private Reactor reactor;

    @Resource
    private VisitorService visitorService;

    @Override
    public PageResult<VisitorPageVO> page(VisitorParam visitorParam) {
        return new PageResult<>(visitorMapper.findPage(PageFactory.defaultPage(), visitorParam));
    }

    @Override
    public List<Visitor> list(VisitorParam visitorParam) {
        QueryWrapper<Visitor> queryWrapper = new QueryWrapper<>();
        if (!visitorParam.getIsSuperAdmin()) {
            queryWrapper.lambda().in(Visitor::getOrgId, visitorParam.getDataScope());
        }
        return visitorService.list(queryWrapper);
    }


    @Override
    public void add(VisitorParam visitorParam) {
        if (!ConstantContextHolder.getRemotePush()) {
            checkDeviceStatus(visitorParam.getOrgId());
        }
        SysOrg sysOrg = sysOrgMapper.selectById(visitorParam.getOrgId());
        if (sysOrg == null || !ObjectUtil.equal(sysOrg.getType(), 2)) {
            throw new ServiceException(500, "请选择访客组!");
        }

        SysOrg company = sysOrgMapper.selectById(visitorParam.getCompanyId());
        Visitor visitor = new Visitor();
        visitor.setSource(1);
        BeanUtil.copyProperties(visitorParam, visitor);
        if (company != null) {
            visitor.setCompanyId(company.getId());
            visitor.setCompanyName(company.getName());
        }
        visitorService.save(visitor);
        // 插入中间表
        List<OrgDevice> orgDevices = orgDeviceMapper.selectList(new LambdaQueryWrapper<OrgDevice>().eq(OrgDevice::getOrgId, visitorParam.getOrgId()));
        for (OrgDevice orgDevice : orgDevices) {
            VisitorDevice memberDevice = new VisitorDevice().setStatus(1).setOrgId(visitor.getOrgId()).setDeviceId(orgDevice.getDeviceId()).setVisitorId(visitor.getId());
            visitorDeviceMapper.insert(memberDevice);
        }
    }


    private void checkDeviceStatus(Long orgId) {
        List<OrgDevice> orgDevices = orgDeviceMapper.selectList(new LambdaQueryWrapper<OrgDevice>().eq(OrgDevice::getOrgId, orgId));
        if (CollectionUtils.isNotEmpty(orgDevices)) {
            List<Long> deviceIds = orgDevices.stream().map(OrgDevice::getDeviceId).collect(Collectors.toList());
            List<DeviceBase> list = deviceBaseService.list(new LambdaQueryWrapper<DeviceBase>()
                    .eq(DeviceBase::getDeviceSyncStatus, 2)
                    .in(DeviceBase::getId, deviceIds));
            if (CollectionUtils.isNotEmpty(list)) {
                throw new ServiceException(500, "设备正在更换用户组！ 请稍后再试！");
            }
        }
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public void delete(VisitorParam visitorParam) {
        Visitor visitor = this.queryVisitor(visitorParam);
        // 发布访客删除事件
        reactor.notify(EventTopic.VISITOR_DELETE, Event.wrap(visitor));
        List<VisitorDevice> visitorDevices = null;
        if (!ConstantContextHolder.getRemotePush()) {
            checkCurrentVisitorStatus(visitor);
            checkDeviceStatus(visitor.getOrgId());
            visitorDevices =
                    visitorDeviceMapper.selectList(new LambdaQueryWrapper<VisitorDevice>().eq(VisitorDevice::getVisitorId, visitor.getId())
                            .in(VisitorDevice::getStatus, MemberDeviceConstant.ADD_FAIL, MemberDeviceConstant.UPDATE_FAIL, MemberDeviceConstant.DELETE_FAIL,
                                    MemberDeviceConstant.SYNC_SUCCESS));
        } else {
            visitorDevices = visitorDeviceMapper.selectList(new LambdaQueryWrapper<VisitorDevice>().eq(VisitorDevice::getVisitorId, visitor.getId())
                    .in(VisitorDevice::getStatus,
                            MemberDeviceConstant.ADD_FAIL,
                            MemberDeviceConstant.UPDATE_FAIL,
                            MemberDeviceConstant.DELETE_FAIL,
                            MemberDeviceConstant.UPDATE,
                            MemberDeviceConstant.ADD,
                            MemberDeviceConstant.SYNC_SUCCESS));
        }
        for (VisitorDevice visitorDevice : visitorDevices) {
            if (ObjectUtil.equal(MemberDeviceConstant.ADD_FAIL, visitorDevice.getStatus())) {
                visitorDeviceMapper.deleteById(visitorDevice.getId());
            } else {
                visitorDeviceMapper.updateById(visitorDevice.setStatus(MemberDeviceConstant.DELETE));
            }
        }
        if (ObjectUtil.equal(visitorParam.getDelFlag(), "1")) {
            long count = visitorDeviceMapper.selectCount(new LambdaQueryWrapper<VisitorDevice>().eq(VisitorDevice::getVisitorId, visitor.getId()));
            if (count == 0) {
                visitorService.removeById(visitorParam.getId());
            } else {
                visitor.setDelFlag("1");
                visitorService.updateById(visitor);
            }
        }
        MemberFeatures memberFeatures = new MemberFeatures();
        memberFeatures.setDwVisitorId(visitor.getId());
        memberFeatures.setType(MemberFeaturesTypeEnum.VISITOR.getValue());
        memberFeatures.setPlatform(DeviceCategory.SUB_TYPE_FACE);
        reactor.notify(EventTopic.MEMBER_FACE_VALUE_DELETE, Event.wrap(memberFeatures));


    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void edit(VisitorParam visitorParam) {
        Visitor visitor = this.queryVisitor(visitorParam);
        SysOrg sysOrg = sysOrgMapper.selectById(visitorParam.getOrgId());

        if (sysOrg == null || !ObjectUtil.equal(sysOrg.getType(), 2)) {
            throw new ServiceException(500, "请选择访客组!");
        }
        if (!ConstantContextHolder.getRemotePush()) {
            checkCurrentVisitorStatus(visitor);
            checkDeviceStatus(visitor.getOrgId());
            checkDeviceStatus(visitorParam.getOrgId());
            if (visitorParam.getVisitEndDate().before(new Date()) && ObjectUtil.equal(visitor.getStatus(), "0")) {
                throw new ServiceException(500, "访客已经过期不允许修改！");
            }
        }
        // 组织变更 新增和删除人员  暂时不支持修改用户组
        if (!ObjectUtil.equal(visitor.getOrgId(), visitorParam.getOrgId())) {

            // 做标记删除人员
            visitorDeviceMapper.updateStateForVisitorId(visitorParam.getId(), 3);
            // 新增人员
            List<OrgDevice> orgDevices = orgDeviceMapper.selectList(new LambdaQueryWrapper<OrgDevice>().eq(OrgDevice::getOrgId, visitorParam.getOrgId()));
            for (OrgDevice orgDevice : orgDevices) {
                VisitorDevice visitorDevice = new VisitorDevice().setStatus(1).setOrgId(visitorParam.getOrgId())
                        .setDeviceId(orgDevice.getDeviceId()).setVisitorId(visitor.getId());
                visitorDeviceMapper.insert(visitorDevice);
            }
            // 修改人员
        } else {
            visitorDeviceMapper.updateStateForVisitorId(visitor.getId(), 2);
        }
        // 访客直接不涉及卡号修改
        //boolean pushCardUpdateEvent = !ObjectUtil.equal(visitorParam.getIcCard(), visitor.getIcCard());

        BeanUtil.copyProperties(visitorParam, visitor);
        visitor.setPushFlag(Boolean.FALSE);
        visitorService.updateById(visitor);
        //// 发布人员卡号变动事件
        //if (pushCardUpdateEvent) {
        //    // 通知其他设备人员卡号变动
        //    reactor.notify(EventTopic.VISITOR_UPDATE_CARD, Event.wrap(visitor.getId()));
        //}
        MemberFeatures memberFeatures = new MemberFeatures();
        memberFeatures.setDwVisitorId(visitor.getId());
        memberFeatures.setType(MemberFeaturesTypeEnum.VISITOR.getValue());
        memberFeatures.setPlatform(DeviceCategory.SUB_TYPE_FACE);
        reactor.notify(EventTopic.MEMBER_FACE_VALUE_DELETE, Event.wrap(memberFeatures));
    }

    @Override
    public Visitor detail(VisitorParam visitorParam) {
        return this.queryVisitor(visitorParam);
    }

    @Override
    public UserImportResultVO importExcel(MultipartFile file) {

        List<DeviceBase> deviceBases = deviceBaseService.list(new LambdaQueryWrapper<DeviceBase>().eq(DeviceBase::getDeviceSyncStatus, 2));
        if (CollectionUtils.isNotEmpty(deviceBases)) {
            throw new ServiceException(500, "设备正在更换用户组！ 请稍后再试！");
        }

        CopyOnWriteArrayList<MemberImportResultPojoVO> memberImportResultPojoVos = new CopyOnWriteArrayList<>();
        // 保存文件
        sysFileInfoService.uploadFile(file, FileTypeEnum.LOCAL);

        AtomicInteger successNum = new AtomicInteger(0);
        AtomicInteger failureNum = new AtomicInteger(0);
        List<VisitorImportVO> visitorImportVOS = PoiUtil.importExcel(file, 0, 1, VisitorImportVO.class);
        if (CollectionUtils.isEmpty(visitorImportVOS)) {
            throw new ServiceException(500, "文件中不存在有效数据!");
        }
        long d = System.currentTimeMillis();
        log.info("====导入开始时间==================================================" + DateUtils.formatDate(new Date()));

        if (visitorImportVOS.size() > 20) {
            log.info("开始多线程导入===");
            List<List<VisitorImportVO>> splitList = ListUtils.partition(visitorImportVOS, visitorImportVOS.size() / 20);
            CountDownLatch countDownLatch = new CountDownLatch(splitList.size());
            ExecutorService executorService = Executors.newFixedThreadPool(splitList.size());
            for (List<VisitorImportVO> oneList : splitList) {
                executorService.execute(() -> {
                    try {
                        signalThreadImport(memberImportResultPojoVos, successNum, failureNum, oneList);
                    } catch (Exception e) {
                        e.printStackTrace();
                    } finally {
                        countDownLatch.countDown();
                    }
                });
            }
            try {
                countDownLatch.await();
            } catch (InterruptedException e) {
                log.error("线程被其他线程中断【{}】", ExceptionUtil.getMessage(e));
            }
        } else {
            log.info("开始单线程导入===");
            signalThreadImport(memberImportResultPojoVos, successNum, failureNum, visitorImportVOS);
        }
        // 有效数据

        log.info("====导入结束时间==================================================" + (System.currentTimeMillis() - d));
        UserImportResultVO memberImportResultVo = new UserImportResultVO();
        memberImportResultVo.setSuccessNum(successNum.get());
        memberImportResultVo.setFailNum(failureNum.get());
        memberImportResultVo.setMemberImportResultPojoVos(memberImportResultPojoVos);
        return memberImportResultVo;
    }

    @Override
    public void export(VisitorParam visitorParam) {
        List<VisitorPageVO> list = visitorMapper.findList(visitorParam);
        list.forEach(x -> {
            if (StringUtils.isNotEmpty(x.getDetectionPhoto())) {
                x.setDetectionPhoto(IpAddressUtil.getImageAddIp(x.getDetectionPhoto()));
            }
            if (StringUtils.isNotEmpty(x.getIdentityPhoto())) {
                x.setIdentityPhoto(IpAddressUtil.getImageAddIp(x.getIdentityPhoto()));
            }
            if (StringUtils.isNotEmpty(x.getPhoto())) {
                x.setPhoto(IpAddressUtil.getImageAddIp(x.getPhoto()));
            }
        });
        PoiUtil.exportExcelWithStream("访客.xls", VisitorPageVO.class, list);
    }

    @Override
    public void cleanVisitor() {
        List<Visitor> visitors = visitorMapper.selectList(new LambdaQueryWrapper<Visitor>().between(Visitor::getVisitEndDate, vip.xiaonuo.core.util.DateUtils.addDay(new Date(), -65), vip.xiaonuo.core.util.DateUtils.addDay(new Date(), -60)));
        List<VisitorParam> collect = visitors.stream().map(x -> new VisitorParam().setId(x.getId())).collect(Collectors.toList());
        collect.forEach(this::delete);
    }

    @Override
    public void approval(Long id) {
        Visitor visitor = visitorMapper.selectById(id);
        // 访客机
        if (ObjectUtil.equal(visitor.getSource(), 3)) {
            // 访客机生成二维码并且发卡 再前端设备打印卡片和打印二维码那块
//            // 生成二维码
//            String fileName = new UUIDGenerator().next().concat(".png");
//            fileOperator.saveQrCode(FileConfig.DEFAULT_BUCKET.concat(File.separator).concat("qrCode"), fileName, "content");
//            visitor.setQrCode(File.separator.concat("qrCode").concat(File.separator).concat(fileName));
//            // 通知设备做新增访客处理
//            reactor.notify(EventTopic.VISITOR_DEVICE_ADD, Event.wrap(visitor.getId()));
            // 小程序
        } else if (ObjectUtil.equal(visitor.getSource(), 2)) {
            // 通知设备做新增访客处理
            reactor.notify(EventTopic.VISITOR_MINIAPP_ADD, Event.wrap(visitor.getId()));
        }
        visitor.setIssuanceOfVouchers(0);
        visitor.setStatus(VisitorConstant.EXAMINATION_PASSD);
        SysLoginUser sysLoginUser = LoginContextHolder.me().getSysLoginUser();
        visitor.setBackApprovalId(sysLoginUser.getId());
        visitorService.updateById(visitor);
    }

    @Override
    public void approvalDenied(Long id) {
        Visitor visitor = visitorMapper.selectById(id);
        visitor.setIssuanceOfVouchers(1);
        SysLoginUser sysLoginUser = LoginContextHolder.me().getSysLoginUser();
        visitor.setBackApprovalId(sysLoginUser.getId());
        visitor.setStatus(VisitorConstant.REVIEW_REJECTION);
        visitor.setApprovalRemake(" 后台审批拒绝 ");
        visitorService.updateById(visitor);
    }

    private void signalThreadImport(List<MemberImportResultPojoVO> memberImportResultPojoVos, AtomicInteger successNum, AtomicInteger failureNum, List<VisitorImportVO> memberUserImportVOS) {
        for (VisitorImportVO importBean : memberUserImportVOS) {
            try {

                if (StringUtils.isBlank(importBean.getName())) {
                    addFailMessage(memberImportResultPojoVos, importBean, "名称为null", failureNum);
                    continue;
                }

                if (StringUtils.isBlank(importBean.getOrgCode())) {
                    addFailMessage(memberImportResultPojoVos, importBean, "组织为null", failureNum);
                    continue;
                }

                if (importBean.getVisitStartDate() == null || importBean.getVisitEndDate() == null) {
                    addFailMessage(memberImportResultPojoVos, importBean, "访客访问时间不能为null", failureNum);
                    continue;
                }

                SysOrg sysOrg = sysOrgMapper.selectOne(new LambdaQueryWrapper<SysOrg>().eq(SysOrg::getCode, importBean.getOrgCode()));
                if (sysOrg == null) {
                    addFailMessage(memberImportResultPojoVos, importBean, "组织编码找不到所属组织!", failureNum);
                    continue;
                }
                if (!ObjectUtil.equal(sysOrg.getType(), 2)) {
                    addFailMessage(memberImportResultPojoVos, importBean, "请填写访客组编码!", failureNum);
                    continue;
                }
                saveBean(successNum, importBean, sysOrg);
            } catch (Exception e) {
                log.error("用户【{}】 发生错误 错误信息【{}】", importBean.getName(), ExceptionUtils.getMessage(e));
                addFailMessage(memberImportResultPojoVos, importBean, "发生异常错误!" + ExceptionUtils.getMessage(e), failureNum);
            }
        }
    }

    public void saveBean(AtomicInteger successNum, VisitorImportVO importBean, SysOrg sysOrg) {
        Visitor visitor = new Visitor();
        visitor.setSource(1);
        BeanUtils.copyProperties(importBean, visitor);
        visitor.setOrgId(sysOrg.getId());
        if (StringUtils.isNotEmpty(importBean.getPhoto())) {
            String url = File.separator.concat("visitorImage").concat(File.separator).concat(importBean.getPhoto());
            visitor.setPhoto(url);
        }
        if (StringUtils.isNotEmpty(importBean.getDetectionPhoto())) {

            List<SysFileInfo> detectionPhoto = sysFileInfoService.list(new LambdaQueryWrapper<SysFileInfo>().eq(SysFileInfo::getFileOriginName, importBean.getDetectionPhoto()).orderByDesc(SysFileInfo::getCreateTime));
            if (CollectionUtils.isNotEmpty(detectionPhoto)) {
                String url = File.separator.concat("visitorImage").concat(File.separator).concat(detectionPhoto.get(0).getFileObjectName());
                visitor.setDetectionPhoto(url);
            }
        }

        if (StringUtils.isNotEmpty(importBean.getIdentityPhoto())) {
            List<SysFileInfo> getIdentityPhoto = sysFileInfoService.list(new LambdaQueryWrapper<SysFileInfo>().eq(SysFileInfo::getFileOriginName, importBean.getIdentityPhoto()).orderByDesc(SysFileInfo::getCreateTime));
            if (CollectionUtils.isNotEmpty(getIdentityPhoto)) {
                String url = File.separator.concat("visitorImage").concat(File.separator).concat(getIdentityPhoto.get(0).getFileObjectName());
                visitor.setIdentityPhoto(url);
            }
        }
        visitorService.save(visitor);
        successNum.incrementAndGet();

        List<OrgDevice> orgDevices = orgDeviceMapper.selectList(new LambdaQueryWrapper<OrgDevice>().eq(OrgDevice::getOrgId, sysOrg.getId()));
        for (OrgDevice orgDevice : orgDevices) {
            VisitorDevice visitorDevice = new VisitorDevice();
            visitorDevice.setVisitorId(visitor.getId()).setDeviceId(orgDevice.getDeviceId()).setOrgId(visitor.getOrgId()).setStatus(MemberDeviceConstant.ADD);
            visitorDeviceMapper.insert(visitorDevice);
        }
    }

    private void addFailMessage(List<MemberImportResultPojoVO> memberImportResultPojoVos, VisitorImportVO importBean, String failMessage, AtomicInteger failureNum) {
        MemberImportResultPojoVO memberImportResultPojoVo = new MemberImportResultPojoVO();
        memberImportResultPojoVo.setName(importBean.getName()).setFailMessage(failMessage);
        memberImportResultPojoVos.add(memberImportResultPojoVo);
        failureNum.incrementAndGet();
    }

    /**
     * 获取访客
     *
     * @author 胡鹏达
     * @date 2022-07-25 09:34:39
     */
    private Visitor queryVisitor(VisitorParam visitorParam) {
        Visitor visitor = visitorService.getById(visitorParam.getId());
        if (ObjectUtil.isNull(visitor)) {
            throw new ServiceException(VisitorExceptionEnum.NOT_EXIST);
        }
        return visitor;
    }

    private void checkCurrentVisitorStatus(Visitor visitor) {
        long count = visitorDeviceMapper.selectCount(new LambdaQueryWrapper<VisitorDevice>().eq(VisitorDevice::getVisitorId, visitor.getId()).in(VisitorDevice::getStatus, MemberDeviceConstant.ADD, MemberDeviceConstant.UPDATE, MemberDeviceConstant.DELETE));
        if (count > 0) {
            throw new ServiceException(500, "设备正在忙碌中！请稍后!");
        }
    }
}
